package controllers.sys;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import models.sys.AdminMenu;
import models.sys.AdminRole;
import models.sys.AdminUser;
import models.sys.AdminUserLog;
import play.Play;
import play.db.jpa.Model;
import play.mvc.With;
import plugin.shiro.AdminPasswordHelper;
import server.sys.AdminServer;
import utils.*;

import javax.persistence.Query;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@With(Secure.class)
public class AdminController extends SystemController {
    /**
     * 首页
     */
    public static void index() {
        JSONObject indexData = new JSONObject();
        AdminUser loginUser = getLoginUser();
        {   //存入登录用户信息
            JSONObject loginUserInfo = new JSONObject();
            loginUserInfo.put("id", loginUser.id);
            loginUserInfo.put("username", loginUser.username);
            loginUserInfo.put("role", loginUser.role.role);
            loginUserInfo.put("realname", loginUser.realname);
            indexData.put("user", loginUserInfo);
        }
        {   //存入菜单信息
            JSONArray tree = new JSONArray();
            AdminRole role = loginUser.role;
            if (role.menus != null && role.menus.size() > 0) {
                // TODO  报错 临时注释掉了
//                role.menus.sort((o1, o2) -> {
//                    if (o1.sortid.equals(o2.sortid)) {
//                        if (o1.id > o2.id)
//                            return 1;
//                        else if (o1.id < o2.id)
//                            return -1;
//                        else
//                            return 0;
//                    } else {
//                        if (o1.sortid > o2.sortid) {
//                            return 1;
//                        } else if (o1.sortid < o2.sortid) {
//                            return -1;
//                        } else {
//                            return 0;
//                        }
//                    }
//                });

                for (AdminMenu menu : role.menus) {
                    JSONObject menujson = new JSONObject();
                    menujson.put("menuid", menu.id);
                    menujson.put("menuname", menu.menuname);
                    menujson.put("menuurl", menu.menuurl);
                    menujson.put("parent", menu.parent);
                    menujson.put("icon", menu.icon);
                    menujson.put("children", new JSONArray());

                    if (menu.parent == -1) {
                        tree.add(menujson);
                    }
                }

                for (AdminMenu menu : role.menus) {
                    JSONObject menujson = new JSONObject();
                    menujson.put("menuid", menu.id);
                    menujson.put("menuname", menu.menuname);
                    menujson.put("menuurl", menu.menuurl);
                    menujson.put("parent", menu.parent);
                    menujson.put("icon", menu.icon);
                    menujson.put("children", new JSONArray());

                    if (menu.parent != -1) {
                        for (int i = 0; i < tree.size(); i++) {
                            JSONObject obj = tree.getJSONObject(i);
                            if (obj.getLong("menuid") == menu.parent) {
                                JSONArray array = obj.getJSONArray("children");
                                array.add(menujson);
                            }
                        }
                    }
                }
            }
            indexData.put("tree", tree);
        }
        {
            indexData.put("title", Play.configuration.getProperty("application.title"));
        }
        render(indexData);
    }

    public static void menu() {
        render();
    }

    public static void menuAdd() {
        render();
    }

    /**
     * 获得菜单列表
     *
     * @param page
     * @param rows
     */
    public static void getMenuList(Integer page, Integer rows) {
        if (Inspector.hasEmpty(page))
            renderJSON(RenderTemplate.parameterError());

        if (rows == null) {
            rows = 10;
        }
        renderJSON(new Pagger(page, rows, AdminMenu.count(), AdminMenu.find("ORDER BY sortid asc").fetch(page, rows)).toJSON());
    }

    /**
     * 根据父级ID获取菜单
     *
     * @param parentid
     */
    public static void getParentMenuList(Long parentid) {
        if (Inspector.hasEmpty(parentid))
            renderJSON(RenderTemplate.parameterError());
        renderJSON(RenderTemplate.success(AdminMenu.find("parent = ?1 ORDER BY sortid asc", parentid).fetch()));
    }

    /**
     * 获取菜单详情接口
     *
     * @param id
     */
    public static void menuDetail(Long id) {
        JSONObject detail = new JSONObject();
        if (Inspector.notEmpty(id)) {
            AdminMenu menu = AdminMenu.findById(id);
            if (menu != null)
                detail = menu.toJSON();
        }
        detail.put("tree", AdminMenu.find("byParent", -1l).fetch());
        render(detail);
    }

    /**
     * 更新或新建菜单(取决于ID字段)
     *
     * @param menu
     */
    public static void upsetMenu(AdminMenu menu) {
        if (Inspector.hasEmpty(menu, menu.menuname, menu.parent))
            renderJSON(RenderTemplate.parameterError());
        menu.save();
        renderJSON(RenderTemplate.success(menu.toJSON()));
    }

    /**
     * 删除菜单
     *
     * @param menu
     */
    public static void deleteMenu(AdminMenu menu) {
        if (Inspector.isEmpty(menu) || !menu.isPersistent())
            renderJSON(RenderTemplate.parameterError());
        {   //删除角色菜单中的对应关系
            String del = "DELETE FROM tb_admin_role_menu WHERE menu_id = ?";
            Query query = Model.em().createNativeQuery(del);
            query.setParameter(1, menu.id);
            query.executeUpdate();
        }
        {   //删除子菜单与自己
            AdminMenu.delete("parent = ?1", menu.id);
            menu.delete();
        }
        renderJSON(RenderTemplate.success());
    }

    /**
     * 用户管理
     */
    public static void user() {
        render();
    }

    /**
     * 获得用户列表
     *
     * @param page
     * @param rows
     */
    public static void getUserList(Integer page, Integer rows) {
        if (Inspector.hasEmpty(page))
            renderJSON(RenderTemplate.parameterError());

        if (rows == null)
            rows = 10;

        List<AdminUser> userlist = AdminUser.find("ORDER BY id asc").fetch(page, rows);
        JSONArray userarr = new JSONArray();
        for (AdminUser user : userlist) {
            userarr.add(user.getInfo());
        }
        System.out.println(userarr);
        renderJSON(new Pagger(page, rows, AdminUser.count(), userarr).toJSON());
    }

    /**
     * 编辑/新增用户页
     *
     * @param id
     */
    public static void userDetail(Long id) {
        JSONObject detail = new JSONObject();
        if (Inspector.notEmpty(id)) {
            AdminUser user = AdminUser.findById(id);
            if (user != null) {
                detail.putAll(user.toJSON());
            }
        }
        detail.put("tree", AdminRole.findAll());
        render(detail);
    }

    /**
     * 更新或者新增系统用户
     *
     * @param user
     */
    public static void upsetUser(Map<String, String> user) {
        MapShell shell = new MapShell(user);
        AdminUser adminUser;
        if (shell.isEmpty("id")) {
            if (shell.hasEmpty("username", "password", "realname", "role_id"))
                renderJSON(RenderTemplate.parameterError());
            adminUser = new AdminUser();
            adminUser.username = shell.getString("username");
        } else {
            if (shell.getLong(user) == 1) {
                renderJSON(RenderTemplate.cannotDoit("此用户不可编辑!"));
            }
            adminUser = AdminUser.findById(shell.getLong("id"));
        }
        if (shell.notEmpty("password"))
            adminUser.password = shell.getString("password");
        adminUser.realname = shell.getString("realname");
        adminUser.enabled = shell.getInteger("enabled", 0);
        adminUser.role = AdminRole.findById(shell.getLong("role_id"));
        AdminPasswordHelper.encryptPassword(adminUser);
        adminUser.save();
        renderJSON(RenderTemplate.success(adminUser.getInfo()));
    }

    /**
     * 删除用户接口
     *
     * @param user
     */
    public static void deleteUser(AdminUser user) {
        if (user != null && user.isPersistent()) {
            if (user.id == 1)
                renderJSON(RenderTemplate.cannotDoit("此用户无法删除!"));
            user.delete();
            renderJSON(RenderTemplate.success());
        }
        renderJSON(RenderTemplate.parameterError());
    }

    /**
     * 修改用户账户状态
     *
     * @param user
     */
    public static void banUser(Map<String, String> user) {
        MapShell shell = new MapShell(user);
        if (shell.hasEmpty("id", "enabled") || shell.valueNot("enabled", 0, 1))
            renderJSON(RenderTemplate.parameterError());
        AdminUser adminUser = AdminUser.findById(shell.getLong("id"));
        if (adminUser.id == 1)
            renderJSON(RenderTemplate.cannotDoit("不能禁用该用户!"));
        adminUser.enabled = shell.getInteger("enabled");
        adminUser.save();
        renderJSON(RenderTemplate.success(adminUser.getInfo()));
    }

    /**
     * 角色管理页
     */
    public static void role() {
        render();
    }

    public static void roleDetail(Long id) {
        JSONObject detail = new JSONObject();
        if (Inspector.notEmpty(id)) {
            AdminRole role = AdminRole.findById(id);
            if (role != null)
                detail.putAll(role.getInfo());
        }
        render(detail);
    }

    public static void roleSet() {
        render();
    }

    /**
     * 获取角色列表
     *
     * @param page
     * @param rows
     */
    public static void getRoleList(Integer page, Integer rows) {
        if (Inspector.hasEmpty(page))
            renderJSON(RenderTemplate.parameterError());

        if (rows == null)
            rows = 10;
        renderJSON(new Pagger(page, rows, AdminRole.count(),
                DBUtils.queryToMapList(
                        Model.em().createNativeQuery("SELECT * FROM topweb.tb_admin_role ORDER BY id ASC LIMIT ?1,?2")
                                .setParameter(1, (page - 1) * rows)
                                .setParameter(2, rows))).toJSON());
    }

    /**
     * 获得角色菜单树
     *
     * @param rid
     */
    public static void getRoleMenuTree(Long rid) {
        if (Inspector.isEmpty(rid))
            renderJSON(RenderTemplate.parameterError());


        renderJSON(RenderTemplate.success(AdminServer.getMenuTreeAcrossRole(AdminRole.findById(rid))));
    }

    /**
     * 获取角色菜单列表
     *
     * @param rid
     * @param mid
     */
    public static void getRoleMenuList(String rid, String mid) {
//        JSONObject json = new JSONObject();
        if (Inspector.hasEmpty(rid, mid)) {
            renderJSON(RenderTemplate.parameterError());
        }
        JSONArray tree = new JSONArray();
        AdminRole role = AdminRole.findById(Long.parseLong(rid));
        List<AdminMenu> menulist = AdminMenu.find("byParent", Long.parseLong(mid)).fetch();
        for (AdminMenu menu : menulist) {
            boolean isInRole = false;
            for (AdminMenu rolemenu : role.menus) {
                if (menu.id == rolemenu.id) {
                    isInRole = true;
                    break;
                }
            }
            JSONObject menuJson = new JSONObject();
            menuJson.put("id", menu.id);
            menuJson.put("name", menu.menuname);
            if ("-1".equals(mid)) {
                menuJson.put("type", "folder");
            } else {
                menuJson.put("type", "item");
            }
            JSONObject params = new JSONObject();
            if (isInRole) {
                params.put("item-selected", true);
            } else {
                params.put("item-selected", false);
            }
            menuJson.put("additionalParameters", params);
            tree.add(menuJson);
        }

        renderJSON(RenderTemplate.success(tree));
    }

    /**
     * 编辑或更新角色信息
     *
     * @param role
     */
    public static void upsetRole(AdminRole role) {
        if (Inspector.hasEmpty(role, role.enabled, role.id))
            renderJSON(RenderTemplate.parameterError());
        else if (Inspector.hasEmpty(role, role.description, role.role))
            renderJSON(RenderTemplate.parameterError());
        if ("superadmin".equals(role.role) || 1 == role.id)
            renderJSON(RenderTemplate.cannotDoit("此角色不可编辑!"));
        if (Inspector.isEmpty(role.id) || !role.isPersistent()) {
            if (AdminRole.count("byRole", role.role) > 0)
                renderJSON(RenderTemplate.usernameRepeat("角色名重复"));
        }
        if ("superadmin".equals(role.role) && role.enabled == 0) {
            renderJSON(RenderTemplate.cannotDoit("不能禁用该角色"));
        }
        role.save();
        renderJSON(RenderTemplate.success(role.getInfo()));
    }

    /**
     * 编辑或更新角色信息
     *
     * @param role
     */
    public static void banRole(AdminRole role) {
        if (Inspector.hasEmpty(role, role.enabled, role.id))
            renderJSON(RenderTemplate.parameterError());
        if (("superadmin".equals(role.role) || 1 == role.id) && role.enabled == 0)
            renderJSON(RenderTemplate.cannotDoit("不能禁用该角色"));
        if (!role.isPersistent()) {
            renderJSON(RenderTemplate.isFailure("没有找到该角色!"));
        }
        role.save();
        renderJSON(RenderTemplate.success(role.getInfo()));
    }

    /**
     * 更新角色菜单关系
     *
     * @param id
     * @param menus
     */
    public static void updateRoleMenu(Long id, List<Long> menus) {
        if (Inspector.hasEmpty(id, menus)) {
            renderJSON(RenderTemplate.parameterError());
        }
        List<AdminMenu> menulist = new ArrayList<>();
        for (Long mid : menus) {
            AdminMenu menu = AdminMenu.findById(mid);
            if (menu.parent != -1) {
                boolean hasParent = false;
                for (AdminMenu pm : menulist) {
                    if (Objects.equals(pm.id, menu.parent)) {
                        hasParent = true;
                        break;
                    }
                }
                if (!hasParent) {
                    AdminMenu parentmenu = AdminMenu.findById(menu.parent);
                    menulist.add(parentmenu);
                }
            }
            menulist.add(menu);
        }
        AdminRole role = AdminRole.findById(id);
        System.out.println(menulist);
        role.menus = menulist;
        role.save();
        renderJSON(RenderTemplate.success(role.menus));
    }

    /**
     * 删除角色(一并删除用户)
     *
     * @param id
     */
    public static void deleteRole(Long id) {
        if (Inspector.isEmpty(id)) {
            renderJSON(RenderTemplate.parameterError());
        }
        AdminRole role = AdminRole.findById(id);
        if ("superadmin".equals(role.role) || 1 == role.id) {
            renderJSON(RenderTemplate.cannotDoit("不能删除该角色"));
        }
        List<AdminUser> users = AdminUser.find("byRole", role).fetch();
        for (AdminUser user : users) {
            user.role = null;
            user.save();
        }
        role.menus = null;
        role.save();
        role.delete();
        renderJSON(RenderTemplate.success());
    }

    /**
     * 用户日志查看
     *
     */
    public static void userLog() {
        render();
    }

    /**
     * 获取用户日志列表
     *
     * @param page
     * @param rows
     */
    public static void getUserLogList(Integer page, Integer rows) {
        if (Inspector.isEmpty(page))
            renderJSON(RenderTemplate.parameterError());
        if (rows == null)
            rows = 10;

        renderJSON(new Pagger(page,rows, AdminUserLog.count(),AdminUserLog.find("ORDER BY logtime").fetch(page,rows)).toJSON());
    }





}
